package com.yibing.test.enumtest;

interface Operation <T extends Number> {
	T apply(T x, T y);
}

enum BasicOperation implements Operation<Double> {
	PLUS("+") { 
		@Override public Double apply(Double x, Double y) {
			return x + y;
		}
	},
	
	MINUS("-") { 
		@Override public Double apply(Double x, Double y) {
			return x - y;
		}
	};

	private String symbol;
	
	BasicOperation(String s) {
		this.symbol = s;
	}
	
	@Override public String toString() {
		return symbol;
	}
	
}

enum ExtendedOperation implements Operation<Double> {
	TIMES("*") { 
		@Override public Double apply(Double x, Double y) {
			return x * y;
		}
	},
	
	DIVIDE("/") { 
		@Override public Double apply(Double x, Double y) {
			return x / y;
		}
	};

	private String symbol;
	
	ExtendedOperation(String s) {
		this.symbol = s;
	}
	
	@Override public String toString() {
		return symbol;
	}
	
}

public class EnumExtened {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Double x = 1.23;
		Double y = 0.23;
		
		test(BasicOperation.class, x, y);
		test(ExtendedOperation.class, x, y);
	}
	
	private static <T extends Enum<T> & Operation<Double>> void test
		(Class<T> opSet, Double x, Double y) {
		for (Operation<Double> op : opSet.getEnumConstants()) {
			System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y));
		}
	}

}
